Make a species list for a Local Government Area (LGA) in Python and R

Knowing what species have been observed in a local area is an important, regular task for ecosystem management and environmental impact assessment. Here we show how to use galah-python to make a species list using layers available in galah-python or using a shapefile, and how to cross-reference this list with threatened species lists determine if threatened species are in your LGA.

Eukaryota
Summaries
Python
R
Authors

Amanda Buyan

Dax Kellie

Published

December 1, 2023

Author

Amanda Buyan
Dax Kellie

Date

1 December 2023

Knowing what species inhabit an area is important for conservation and ecosystem management. It is also useful to know how common or rare each species might be, or how many species are threatened or endangered in a given area.

Species lists are a common tool to find what species are in a given area for monitoring and environmental impact assessments. Often, these lists are asked to be produced for specific regions like Local Government Areas (LGAs) or specific monitoring locations within a region.

In this post, we will show you how to generate a species list for an Local Government Area—the Yass Valley—over the past year in either Python or R.

Make a species list

There are two ways to narrow a query to return information for a specific region:

  • Using fields available in galah-python (downloaded from the ALA)
  • Using a shapefile

The method you choose depends on whether the region you wish to return species for is already within galah-python, or whether you require a list for a more specific area defined by a shapefile.

Let’s go through each of the methods in turn to return a list of species in the Yass Valley in 2023.

First, let’s import galah.

import galah

Use an existing spatial field

Search for fields

Let’s find which fields and layers exist within galah-python to narrow our query to a specific LGA region and year.

We can use the search_all() function to search for many types of information in galah-python. Let’s use it to look up what fields contain the word “year”. Our search returns several options, though the best option seems to be the field id "year".

galah.search_all(fields="year")
                    id                                        description   type                                               link
0                 year  The year in which an occurrence was observed. ...  field  https://github.com/AtlasOfLivingAustralia/ala-...
1         endDayOfYear          http://rs.tdwg.org/dwc/terms/endDayOfYear  field                                                NaN
2        datePrecision  The precision of the date information for the ...  field                                                NaN
3       occurrenceYear  Year ranges for a search. Calculated based on ...  field                                                NaN
4       startDayOfYear        http://rs.tdwg.org/dwc/terms/startDayOfYear  field                                                NaN
5  namePublishedInYear   http://rs.tdwg.org/dwc/terms/namePublishedInYear  field                                                NaN

To double check whether a given field contains the information we are interested in, we can use show_values() to see what values are within the "year".

galah.show_values(field="year")
    field category
0    year     2022
1    year     2021
2    year     2020
3    year     2019
4    year     2018
..    ...      ...
280  year     1755
281  year     1756
282  year     1762
283  year     1763
284  year     1764

[285 rows x 2 columns]

Let’s use the same process to search for a field containing spatial data of Local Government Areas. Our search returns a few options.

galah.search_all(fields="Local Government Areas")
        id                                        description    type link
0     cl23  Local Government Areas 2012 deprecated LGA Bou...  layers     
1    cl959  Local Government Areas 2011 Local Government A...  layers     
2   cl2012  NSW Local Land Services Regions NSW Local Land...  layers     
3  cl10923  Local Government Areas PSMA 2018 Local Governm...  layers     

The field cl10923 seems to be contain the most recent data from 2018. Let’s check what this values this field contains.

galah.show_values(field="cl10923")
       field                      category
0    cl10923                 BRISBANE CITY
1    cl10923          EAST GIPPSLAND SHIRE
2    cl10923          GREATER GEELONG CITY
3    cl10923  PASTORAL UNINCORPORATED AREA
4    cl10923          MORETON BAY REGIONAL
..       ...                           ...
555  cl10923                  WAGAIT SHIRE
556  cl10923   WOORABINDA ABORIGINAL SHIRE
557  cl10923  WUJAL WUJAL ABORIGINAL SHIRE
558  cl10923    CHERBOURG ABORIGINAL SHIRE
559  cl10923                 BELYUEN SHIRE

[560 rows x 2 columns]

We can use search for the value “Yass Valley” specifically with search_values().

galah.search_values(field="cl10923", value = "YASS VALLEY")
     field             category
0  cl10923  YASS VALLEY COUNCIL
Note

Each spatial layer has a two letter code, along with a number to identify it. The abbreviations are as follows:

  • cl = contextual layer (i.e. boundaries of LGAs, Indigenous Protected Areas, States/Territories etc.)
  • 10923 = number associated with the spatial layer in the atlas

Download data

Now we can build a query to return species observed in Yass Valley over 2023. We can use atlas_species() to return a species list, and use the filters argument to narrow our query.

galah.atlas_species(filters=["year=2023","cl10923=YASS VALLEY COUNCIL"])
                                               Species                       Species Name Scientific Name Authorship Taxon Rank   Kingdom      Phylum          Class           Order        Family        Genus               Vernacular Name
0    https://biodiversity.org.au/afd/taxa/5291343e-...                 Gymnorhina tibicen             (Latham, 1801)    species  Animalia    Chordata           Aves   Passeriformes     Artamidae   Gymnorhina             Australian Magpie
1    https://biodiversity.org.au/afd/taxa/97a59c84-...    Rhipidura (Rhipidura) albiscapa                Gould, 1840    species  Animalia    Chordata           Aves   Passeriformes  Rhipiduridae    Rhipidura                  Grey Fantail
2    https://biodiversity.org.au/afd/taxa/760401df-...          Malurus (Malurus) cyaneus              (Ellis, 1782)    species  Animalia    Chordata           Aves   Passeriformes     Maluridae      Malurus             Superb Fairy-wren
3    https://biodiversity.org.au/afd/taxa/2c33a1fd-...         Cacatua (Cacatua) galerita             (Latham, 1790)    species  Animalia    Chordata           Aves  Psittaciformes    Cacatuidae      Cacatua      Sulphur-crested Cockatoo
4    https://biodiversity.org.au/afd/taxa/5e0f496f-...  Platycercus (Platycercus) elegans             (Gmelin, 1788)    species  Animalia    Chordata           Aves  Psittaciformes   Psittacidae  Platycercus               Crimson Rosella
..                                                 ...                                ...                        ...        ...       ...         ...            ...             ...           ...          ...                           ...
823  https://id.biodiversity.org.au/taxon/apni/5141...                Pterostylis jonesii                 G.N.Backh.    species   Plantae  Charophyta  Equisetopsida     Asparagales   Orchidaceae  Pterostylis                           NaN
824  https://id.biodiversity.org.au/taxon/apni/5141...             Pterostylis multiflora     (D.L.Jones) G.N.Backh.    species   Plantae  Charophyta  Equisetopsida     Asparagales   Orchidaceae  Pterostylis  Mountain Brown-tip Greenhood
825  https://id.biodiversity.org.au/taxon/apni/5141...            Pterostylis pedunculata                      R.Br.    species   Plantae  Charophyta  Equisetopsida     Asparagales   Orchidaceae  Pterostylis                    Maroonhood
826  https://id.biodiversity.org.au/taxon/apni/5141...                Thelymitra ixioides                        Sw.    species   Plantae  Charophyta  Equisetopsida     Asparagales   Orchidaceae   Thelymitra             Dotted Sun Orchid
827  https://id.biodiversity.org.au/taxon/ausmoss/1...                 Thuidiopsis sparsa  (Hook.f. & Wilson) Broth.    species   Plantae   Bryophyta      Bryopsida        Hypnales   Thuidiaceae  Thuidiopsis                           NaN

[828 rows x 11 columns]

To add the observation count for each species, add counts=True.

species_yass = galah.atlas_species(filters=["year=2023","cl10923=YASS VALLEY COUNCIL"],counts=True)
species_yass
                                               Species                       Species Name Scientific Name Authorship Taxon Rank   Kingdom      Phylum          Class           Order        Family        Genus               Vernacular Name  Number of records
0    https://biodiversity.org.au/afd/taxa/5291343e-...                 Gymnorhina tibicen             (Latham, 1801)    species  Animalia    Chordata           Aves   Passeriformes     Artamidae   Gymnorhina             Australian Magpie                332
1    https://biodiversity.org.au/afd/taxa/97a59c84-...    Rhipidura (Rhipidura) albiscapa                Gould, 1840    species  Animalia    Chordata           Aves   Passeriformes  Rhipiduridae    Rhipidura                  Grey Fantail                252
2    https://biodiversity.org.au/afd/taxa/760401df-...          Malurus (Malurus) cyaneus              (Ellis, 1782)    species  Animalia    Chordata           Aves   Passeriformes     Maluridae      Malurus             Superb Fairy-wren                249
3    https://biodiversity.org.au/afd/taxa/2c33a1fd-...         Cacatua (Cacatua) galerita             (Latham, 1790)    species  Animalia    Chordata           Aves  Psittaciformes    Cacatuidae      Cacatua      Sulphur-crested Cockatoo                238
4    https://biodiversity.org.au/afd/taxa/5e0f496f-...  Platycercus (Platycercus) elegans             (Gmelin, 1788)    species  Animalia    Chordata           Aves  Psittaciformes   Psittacidae  Platycercus               Crimson Rosella                201
..                                                 ...                                ...                        ...        ...       ...         ...            ...             ...           ...          ...                           ...                ...
823  https://id.biodiversity.org.au/taxon/apni/5141...                Pterostylis jonesii                 G.N.Backh.    species   Plantae  Charophyta  Equisetopsida     Asparagales   Orchidaceae  Pterostylis                           NaN                  1
824  https://id.biodiversity.org.au/taxon/apni/5141...             Pterostylis multiflora     (D.L.Jones) G.N.Backh.    species   Plantae  Charophyta  Equisetopsida     Asparagales   Orchidaceae  Pterostylis  Mountain Brown-tip Greenhood                  1
825  https://id.biodiversity.org.au/taxon/apni/5141...            Pterostylis pedunculata                      R.Br.    species   Plantae  Charophyta  Equisetopsida     Asparagales   Orchidaceae  Pterostylis                    Maroonhood                  1
826  https://id.biodiversity.org.au/taxon/apni/5141...                Thelymitra ixioides                        Sw.    species   Plantae  Charophyta  Equisetopsida     Asparagales   Orchidaceae   Thelymitra             Dotted Sun Orchid                  1
827  https://id.biodiversity.org.au/taxon/ausmoss/1...                 Thuidiopsis sparsa  (Hook.f. & Wilson) Broth.    species   Plantae   Bryophyta      Bryopsida        Hypnales   Thuidiaceae  Thuidiopsis                           NaN                  1

[828 rows x 12 columns]

To save this species list as a csv, we can use to_csv() from the pandas dataframe package.

species_yass.to_csv("Species_List_Yass_Valley_Counts_ALA_Spatial_Filter.csv")

Shapefile

Download shapefile

Let’s download the latest Local Government Areas data from the Australian Bureau of Statistics Digital Boundary files page. Find “Local Government Areas - 2023 - Shapefile” and click “Download ZIP”. Save the zip folder in your current directory and unzip it.

We’ll use read_file() from geopandas to load our shapefile.

import geopandas as gpd
LGAs_2023 = gpd.read_file("LGA_2023_AUST_GDA2020.shp")
LGAs_2023
    LGA_CODE23                             LGA_NAME23 STE_CODE21                    STE_NAME21 AUS_CODE21         AUS_NAME21    AREASQKM                                         LOCI_URI21                                           geometry
0        10050                                 Albury          1               New South Wales        AUS          Australia    305.6386  https://linked.data.gov.au/dataset/asgsed3/LGA...  POLYGON ((146.86566 -36.07292, 146.86512 -36.0...
1        10180                               Armidale          1               New South Wales        AUS          Australia   7809.4406  https://linked.data.gov.au/dataset/asgsed3/LGA...  POLYGON ((152.38816 -30.52639, 152.38812 -30.5...
2        10250                                Ballina          1               New South Wales        AUS          Australia    484.9692  https://linked.data.gov.au/dataset/asgsed3/LGA...  MULTIPOLYGON (((153.57106 -28.87381, 153.57106...
3        10300                              Balranald          1               New South Wales        AUS          Australia  21690.7493  https://linked.data.gov.au/dataset/asgsed3/LGA...  POLYGON ((143.00433 -33.78164, 143.01538 -33.7...
4        10470                               Bathurst          1               New South Wales        AUS          Australia   3817.8645  https://linked.data.gov.au/dataset/asgsed3/LGA...  POLYGON ((149.84877 -33.52784, 149.84864 -33.5...
..         ...                                    ...        ...                           ...        ...                ...         ...                                                ...                                                ...
561      89799  Migratory - Offshore - Shipping (ACT)          8  Australian Capital Territory        AUS          Australia         NaN  https://linked.data.gov.au/dataset/asgsed3/LGA...                                               None
562      99399            Unincorp. Other Territories          9             Other Territories        AUS          Australia    105.8806  https://linked.data.gov.au/dataset/asgsed3/LGA...  MULTIPOLYGON (((167.94747 -29.12757, 167.94748...
563      99499                  No usual address (OT)          9             Other Territories        AUS          Australia         NaN  https://linked.data.gov.au/dataset/asgsed3/LGA...                                               None
564      99799   Migratory - Offshore - Shipping (OT)          9             Other Territories        AUS          Australia         NaN  https://linked.data.gov.au/dataset/asgsed3/LGA...                                               None
565      ZZZZZ                      Outside Australia          Z             Outside Australia        ZZZ  Outside Australia         NaN  https://linked.data.gov.au/dataset/asgsed3/LGA...                                               None

[566 rows x 9 columns]

Now let’s use to_crs() to set the Coordinate Reference System (CRS) of our shapefile. A CRS refers to how coordinates on the spherical earth are oriented onto a flat, two-dimensional map. ALA observations are projected using WGS84 (the standard used in cartography and GPS), also known as EPSG:4326.

LGAs_2023 = LGAs_2023.to_crs(4326)
LGAs_2023.plot(edgecolor = "#5A5A5A", linewidth = 0.5, facecolor = "white", figsize = (12,5))

We’ll filter our shapefile to only Yass Valley.

The column LGA_NAME23 appears to contain names we can use to filter our Dataframe. Let’s filter LGA_NAME23 to return only the row containing Yass Valley.

yass_valley = LGAs_2023[LGAs_2023['LGA_NAME23'] == "Yass Valley"]
yass_valley
    LGA_CODE23   LGA_NAME23 STE_CODE21       STE_NAME21 AUS_CODE21 AUS_NAME21  AREASQKM                                         LOCI_URI21                                           geometry
127      18710  Yass Valley          1  New South Wales        AUS  Australia  3995.017  https://linked.data.gov.au/dataset/asgsed3/LGA...  POLYGON ((148.58152 -34.80679, 148.58153 -34.8...

The column geometry contains information to draw our LGA shape. Let’s select just this column.

yass_valley["geometry"]
127    POLYGON ((148.58152 -34.80679, 148.58153 -34.8...
Name: geometry, dtype: geometry

Now that we have the polygon stored as yass_valley_geometry, we can pass it to the polygon argument of atlas_species(). We can also narrow our query to only 2023 observations by adding year to filters, and add the observation count of each species by addint counts=True.